| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156 |
1×
42×
42×
1×
42×
42×
42×
4×
42×
42×
38×
38×
38×
38×
38×
608×
38×
38×
114×
38×
152×
152×
16×
38×
38×
38×
76×
29×
29×
29×
38×
23×
27×
27×
27×
27×
27×
38×
7×
12×
10×
10×
5×
5×
38×
38×
38×
38×
38×
38×
| 'use strict';
angular.module('mgcrea.ngStrap.popover', ['mgcrea.ngStrap.tooltip'])
.provider('$popover', function () {
var defaults = this.defaults = {
animation: 'am-fade',
customClass: '',
// uncommenting the next two lines will break backwards compatability
// prefixClass: 'popover',
// prefixEvent: 'popover',
container: false,
target: false,
placement: 'right',
templateUrl: 'popover/popover.tpl.html',
contentTemplate: false,
trigger: 'click',
keyboard: true,
html: false,
title: '',
content: '',
delay: 0,
autoClose: false
};
this.$get = function ($tooltip) {
function PopoverFactory (element, config) {
// Common vars
var options = angular.extend({}, defaults, config);
var $popover = $tooltip(element, options);
// Support scope as string options [/*title, */content]
if (options.content) {
$popover.$scope.content = options.content;
}
return $popover;
}
return PopoverFactory;
};
})
.directive('bsPopover', function ($window, $sce, $popover) {
var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;
return {
restrict: 'EAC',
scope: true,
link: function postLink (scope, element, attr) {
var popover;
// Directive options
var options = {scope: scope};
angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'container', 'delay', 'trigger', 'html', 'animation', 'customClass', 'autoClose', 'id', 'prefixClass', 'prefixEvent'], function (key) {
if (angular.isDefined(attr[key])) options[key] = attr[key];
});
// use string regex match boolean attr falsy values, leave truthy values be
var falseValueRegExp = /^(false|0|)$/i;
angular.forEach(['html', 'container', 'autoClose'], function (key) {
if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;
});
// bind functions from the attrs to the show and hide events
angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {
var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);
if (angular.isDefined(attr[bsKey])) {
options[key] = scope.$eval(attr[bsKey]);
}
});
// should not parse target attribute (anchor tag), only data-target #1454
var dataTarget = element.attr('data-target');
Iif (angular.isDefined(dataTarget)) {
if (falseValueRegExp.test(dataTarget)) {
options.target = false;
} else {
options.target = dataTarget;
}
}
// Support scope as data-attrs
angular.forEach(['title', 'content'], function (key) {
if (attr[key]) {
attr.$observe(key, function (newValue, oldValue) {
scope[key] = $sce.trustAsHtml(newValue);
Iif (angular.isDefined(oldValue)) {
requestAnimationFrame(function () {
if (popover) popover.$applyPlacement();
});
}
});
}
});
// Support scope as an object
if (attr.bsPopover) {
scope.$watch(attr.bsPopover, function (newValue, oldValue) {
Eif (angular.isObject(newValue)) {
angular.extend(scope, newValue);
} else {
scope.content = newValue;
}
Eif (angular.isDefined(oldValue)) {
requestAnimationFrame(function () {
Iif (popover) popover.$applyPlacement();
});
}
}, true);
}
// Visibility binding support
if (attr.bsShow) {
scope.$watch(attr.bsShow, function (newValue, oldValue) {
if (!popover || !angular.isDefined(newValue)) return;
if (angular.isString(newValue)) newValue = !!newValue.match(/true|,?(popover),?/i);
if (newValue === true) {
popover.show();
} else {
popover.hide();
}
});
}
// Viewport support
Iif (attr.viewport) {
scope.$watch(attr.viewport, function (newValue) {
if (!popover || !angular.isDefined(newValue)) return;
popover.setViewport(newValue);
});
}
// Initialize popover
popover = $popover(element, options);
// Garbage collection
scope.$on('$destroy', function () {
Eif (popover) popover.destroy();
options = null;
popover = null;
});
}
};
});
|